/********************************************************************************
  * @file    projecttabwidget.h
  * @author  Lun Li
  * @version V2.2.0
  * @date    2022.7.8
  * @brief   This file contains all the functions prototypes for ProjectTabWidget.
  ******************************************************************************/

#ifndef PROJECTTABWIDGET_H
#define PROJECTTABWIDGET_H

#include <QActionGroup>
#include <QTabWidget>
#include "project.h"
#include "projectfiletab.h"
#include "projectstructuretab.h"
#include "programconfig.h"
#include "newprojectwizard.h"
#include "newsourcewizard.h"
#include "compileprocess.h"
#include "waveprocess.h"
#include "signalconnection.h"
#include "actionteam.h"

/************
  * ProjectTabWidget类，用于管理工程相关的操作
  ***********/
class ProjectTabWidget : public QTabWidget
{
    Q_OBJECT
public:

    // 按钮枚举
    enum Actions {
        NewProject, OpenProject, CloseProject,
        NewSource, AddSource,
        OpenSource, RemoveSource,
        Compile, CompileAll, CompileProject, Run, StopCompile, ShowWave
    };
    explicit ProjectTabWidget(ProgramConfig *config, QWidget *parent = nullptr);
    ~ProjectTabWidget();

    // 获取按钮列表
    const QList<QAction *> &actionList() const;

    // 通过文件路径查找文件
    Source *fileFromPath(const QString &path);

public slots:

    // 打开工程
    void openProject(const QString &projectFilePath);

    // 向工程内添加源文件
    void addSource(const QString &sourcePath);

    // 编译工程
    void compileSources(QList<Source *>files, bool merge = false);

    // 运行某一编译命令
    void runCompileCmd(const QString &command);

    // 运行某一显示波形的命令
    void runWaveCmd(const QString &cmd);

    // 各按钮按下时对应的槽函数
    void on_newProjectButtonClicked();
    void on_openProjectButtonClicked();
    void on_closeProjectButtonClicked();
    void on_newSourceButtonClicked();
    void on_addSourceButtonClicked();
    void on_openSourceButtonClicked();
    void on_removeSourceButtonClicked();
    void on_compileButtonClicked();
    void on_compileAllButtonClicked();
    void on_compileProjectButtonClicked();
    void on_runButtonClicked();
    void on_stopCompileButtonClicked();
    void on_showWaveButtonClicked();

signals:
    // 需要编译某源文件
    void compileFilesRequested(const QList<Source *>&files, Project *project, bool merge);

    // 需要运行某源文件
    void runFileRequested(Source *file, Project *project);

    // 需要执行某编译指令
    void compileCommandRequested(const QString &command);

    // 需要显示波形
    void showWaveRequested(const QString &command);

    // 需要向波形内添加变量
    void addWaveCommandRequested(const QString &command);

    // 需要打开文件
    void fileNeedOpened(Source *file);

    // 需要关闭文件
    void fileNeedClosed(Source *file);

    // 需要保存文件
    void fileNeedSaved(Source *file);

    // 工程已打开
    void projectOpened();

    // 工程已关闭
    void projectClosed();

    // 打开错误对应的文件及行
    void showErrorLineRequested(Source *file, int lineNumber);

private:
    ProjectFileTab *projectFileTab;
    ProjectStructureTab *projectStructureTab;

    Project *curProject;
    QList<QAction *> m_actionList;
    ActionTeam projectActionTeam;
    ActionTeam fileActionTeam;
    ActionTeam compileActionTeam;
    ProgramConfig *m_config;
    CompileProcess *compProc;
    WaveProcess *waveProc;
    QThread *compThread;
    QThread *waveThread;

    QMenu *projectContextMenu;
    QMenu *fileContextMenu;

    void initializeActionList();

    QString m_originalEnv;

private slots:
    // 工程文件树的当前选定文件发生变化
    void on_projectTreeCurrentChanged(const QModelIndex &index);

    // 用户双击工程文件树中的某一个文件
    void on_projectTreeItemDoubleClicked(const QModelIndex &index);

    // 用户在工程文件树点击右键
    void on_projectTreeMenuRequested(const QPoint &pos);

    // 用户在变量列表点击添加变量
    void on_addingVariableRequested(const QString &name);
};

#endif // PROJECTTABWIDGET_H
